// Queue.cpp -- Queue and Customer methods

#include <cstdlib>  // (or stdlib.h) for rand()
#include "Queue.h"

// Queue methods
Queue::Queue(int qs) : qSize(qs) {
    front = rear = nullptr;
    items = 0;
}

Queue::~Queue() {
    Node *temp;
    // while queue is not yet empty
    while (front != nullptr) {
        temp = front;           // save address of front item
        front = front->next;    // reset pointer to next item
        delete temp;            // delete former front
    }
}

bool Queue::isEmpty() const {
    return items == 0;
}

bool Queue::isFull() const {
    return items == qSize;
}

int Queue::queueCount() const {
    return items;
}

// Add item to queue
bool Queue::enqueue(const Item &item) {
    if (isFull())
        return false;
    Node * add = new Node;   // create Map
    // on failure, new throws std::bad_alloc exception
    add->item = item;   // set Map pointers
    add->next = nullptr;
    ++items;
    if (front == nullptr)   // if queue is empty,
        front = add;        // place item at front
    else
        rear->next = add;   // else place at rear
    rear = add;             // have rear point to new Map
    return true;
}

// Place front item into item variable and remove from queue
bool Queue::dequeue(Item &item) {
    if (front == nullptr)
        return false;
    item = front->item; // set item to first item in queue
    --items;
    Node *temp = front; // save location of first item
    front = front->next;// reset front to next item
    delete temp;        // delete former first item
    if (items == 0)
        rear = nullptr;
    return true;
}

// customer method

// when is the time at which the customer arrives
// the arrival time is set to when and the processing
// time set to a random value in range 1 - 3
void Customer::set(long when) {
    processTime = std::rand() % 3 + 1;
    arrive = when;
}
